<?php

namespace common\observer\task\version;

use common\model\EntityModel;
use common\model\TaskMemberModel;
use common\model\TaskRelationModel;
use common\service\StatusService;
use common\service\TaskAssembleService;
use malkusch\lock\mutex\PHPRedisMutex;
use support\bootstrap\Redis;
use think\Hook;
use Throwable;
use common\model\TaskModel;
use support\SingletonTrait;
use common\model\ProjectModel;
use common\model\VersionModel;
use common\service\OrderService;
use common\model\OrderTaskListModel;
use Webman\Stomp\RetryAbleConsumer;
use teamones\dbeventObserver\interfaces\SplSubject;
use teamones\dbeventObserver\interfaces\SplObserver;

/**
 * 任务发布版本 通知下游文件更新
 */
class VersionPublishNotifyRelateTask implements SplObserver
{
    use SingletonTrait;

    /**
     * @inheritDoc
     */
    function update(SplSubject $subject): void
    {
        $version = $subject->getSubjectData();
        $updateData = $subject->getSplNewData();
        if (!isset($updateData['is_publish']) || $updateData['is_publish'] == "no") {
            return;
        }

        $task = model(TaskModel::class)->find($version['link_id']);
        if (empty($task) || !in_array($task['step_type'], ['step'])) {
            return;
        }

        $relateTaskList = model(TaskRelationModel::class)
            ->setSuffix(sprintf('_project_%d', $task['project_id'] ?? 0))
            ->alias('task_relation')
            ->join('task on task.id = task_relation.source_task_id')
            ->where([
                'task_relation.target_task_id' => $task['id'],
                'task.json->>"$.task_status"' => ['in', StatusService::getInstance()->byCodeMap(['closed, not_started'], true, 'id')],
                'relation_type' => 'upstream',
            ])
            ->field('task.*')
            ->group('task.id')
            ->select();

        if (empty($relateTaskList)) {
            return;
        }

        $entityIdList = array_column($relateTaskList, 'entity_id');
        $entityIdList[] = $task['entity_id'];
        $relateEntity = model(EntityModel::class)
            ->where([
                'id' => ['in', $entityIdList],
            ])
            ->select();
        $relateEntityMap = array_column($relateEntity, null, 'id');

        $taskName = TaskAssembleService::getInstance()->getNotifyTaskName($relateEntityMap[$task['entity_id']], $task);

        foreach ($relateTaskList as $relateTask) {
            $hookData = [
                'type' => 'task_finish_informing_downstream',
                'data' => [
                    'task' => $relateTask,
                    'entity' => $relateEntityMap[$relateTask['entity_id']] ?? [],
                    'current_task_name' => $taskName,
                ]
            ];
            Hook::listen('task_done_with_file_after', $hookData);
        }

    }
}
